package com.attilax.sql;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

import aaaCfg.IocX4nodb;
 










import com.attilax.coll.ListX;
import com.attilax.collection.listUtil;
import com.attilax.db.MysqlDMLSql;
import com.attilax.io.filex;
import com.attilax.ioc.IocXq214;
import com.attilax.jql.DataTypeUnicomMysql;
import com.attilax.lang.MapX;
import com.attilax.lang.text.strUtil;
import com.attilax.store.OrmStoreService;
import com.google.inject.Inject;

public class Dsl2sqlService  {
	
	public static void main(String[] args) {
		//IocX4nodb.db=new ThreadLocal<>();
		IocX4nodb.db.set("shopedb");
		System.setProperty("apptype", "bet");
		OrmStoreService ormSvr = IocXq214.getBean(OrmStoreService.class);
		Dsl2sqlService js=IocXq214.getBean(Dsl2sqlService.class);
		Map m=new HashMap();
//		r.put("$table", "底单申请表");
//		r.put("$db", "shopedb");
//		r.put("$op", "merge");
//		r.put("kwidi", "shopedb_kwidi");
//		r.put("img_col", "shopedb_imgcol");
		
		m.put("$table", "wxb_order");
	//	m.put("$tabletype", "view");
	//	m.put("$view_store_path","com/attilax/order");
		m.put("$op", "insert");
		m.put("good_id","2005");
		m.put("order_id",filex.getUUidName());
	//	System.out.println( js.saveOrMeger(r));
		System.out.println( js.toInsertSql(m));
		//saveOrMeger
		System.out.println("--f4");
	}

	@Inject
	DbMetaService metaSvr;
	String prikey;
	public String saveOrMeger(Map req) {
		String table = getTable(req);
		String op = (String) req.get("$op");
		if(op==null)
			 op = (String) req.get("op");
		  prikey = metaSvr.getPrimaryKey(req);
		if (req.get(prikey) == null || req.get(prikey).toString().trim().length() == 0)
			return toInsertSql(req);
		else
			return update(req);

	}

	public void delete(Map req) {
		// TODO Auto-generated method stub

	}
/**
 * q41 
 * @param req
 * @return
 */
	public String update(Map req) {
		String table = getTable(req);
		Map req_flted = fltMap(req, table);
		if(req_flted.keySet().size()==0)
			throw new RuntimeException("req_flted field is empty ");
	//	calc_cols4sql_n_valsArr(req_flted);
		  prikey = metaSvr.getPrimaryKey(req);
		  ColumnsDefs=  metaSvr.getColumns(null, table);
		SqlKvUtil sqlKvUtil = new SqlKvUtil();
		sqlKvUtil.prikey=prikey;
		sqlKvUtil.ColumnsDefs=ColumnsDefs;
		String kvs=sqlKvUtil.toUpSqlKvPart(req_flted);
		
		String prikey_val = (String)req.get(prikey);
		if(StringUtils.isNotEmpty(prikey_val))  //q418 pk first for comparti.
			return getUpdateSqlByPrikeyMode(table,kvs,prikey,prikey_val);
		if(StringUtils.isEmpty(prikey_val) && strUtil.isNotEmpty( req,"$where"))
		{
			return getUpdateSqlByWhereMode(table,kvs,req.get("$where").toString());
		}
		throw new RuntimeException("get update sql fail");

	}
	
	private String getUpdateSqlByWhereMode(String table, String kvs, String where) {
		String sql = "update @tab@ set @kvs@  where $where$";
		sql = sql.replace("@tab@", table);
		sql = sql.replace("@kvs@", kvs);		 
		sql = sql.replace("@prikey@", prikey);
	
		sql = sql.replace(" $where$",where);
		return sql;
	}

	private String getUpdateSqlByPrikeyMode(String table, String kvs,
		String prikey2, String prikey_val) {
		String sql = "update @tab@ set @kvs@  where @prikey@='@pkVal@'";
		sql = sql.replace("@tab@", table);
		sql = sql.replace("@kvs@", kvs);		 
		sql = sql.replace("@prikey@", prikey);
	
		sql = sql.replace("@pkVal@",prikey_val.toString()  );
		return sql;
//	return null;
}

	public String query(Map req) {
		
		String where=null;
		try {
			where=req.get("$where").toString();
		} catch (Exception e) {
			// TODO: handle exception
		}
	
		String s="select * from $tab$ ";
		s=s.replace("$tab$", req.get("$table").toString());
		if(where!=null)
			s=s+" where "+where;
		return s;
		 

	}

	List<Map> ColumnsDefs;

	@SuppressWarnings("all")
	public String toInsertSql(Map req) {
		
		String table = getTable(req);
		Map req_flted = fltMap(req, table);
		if(req_flted.keySet().size()==0)
			throw new RuntimeException("req_flted field is empty ");
	//	calc_cols4sql_n_valsArr(req_flted);
		  prikey = metaSvr.getPrimaryKey(req);
		  ColumnsDefs=  metaSvr.getColumns(null, table);
		SqlKvUtil sqlKvUtil = new SqlKvUtil();
		sqlKvUtil.prikey=prikey;
		sqlKvUtil.ColumnsDefs=ColumnsDefs;
		String[] a=sqlKvUtil.toInsertSqlKVPart(req_flted);
		String sql = "insert into @tab@(@cols@)values(@vals@)";
		sql = sql.replace("@tab@", table);
		sql = sql.replace("@cols@", a[0]);
		sql = sql.replace("@vals@", a[1]);
		return sql;

	}

	private String getTable(Map req) {
		String table = (String) req.get("$table");
		if(table==null)
			 table = (String) req.get("table");
		if(table==null)
			 table = (String) req.get("$tb");
		if(table==null)
			throw new RuntimeException("cant get table var");
		return table;
	}




	Map colTypeMap = new HashMap();
//	@
	/**
	 * ccc
	 */
	List<Map>  getColumnsRzt;
	public Map reqMap;
	private Map fltMap(Map req, String table) {
		reqMap=req;
		List<Map> li = metaSvr.getColumns(req);
		
		for (Map col_map : li) {
			colTypeMap.put(col_map.get("COLUMN_NAME") , col_map.get("TYPE_NAME"));
		//	colTypeMap.put("TYPE_NAME", );
		}
		Set<String> cols = metaSvr.getColumns_set(req);

		try {
			String line="table:"+table+"  getColumns_size:"+li.size()+"  cols_size:"+cols.size();
			filex.saveLog(line, "e:\\logQ4_fltMap");
		} catch (Exception e) {
			System.out.println("--fltMap:"+e.getMessage());
		}
	
		Map ret = MapX.reduce(req, cols);
		return ret;
	}
	  @Inject
		public		 SqlService sqlSrv;
	

	public String dsl2sql(Map m) {
		 if(m.get("$op").equals("insert"))
				return toInsertSql(m);
		 if(m.get("$op").equals("update"))
				return update(m);
		 if(m.get("$op").equals("merge"))
		 {
		return	 saveOrMeger(m);
		 }
		 if(m.get("$op").equals("select"))
		 {
		return	 query(m);
		 }
		 
		return null;
	}

}
